/*! \file strBuffer.c \brief Multipurpose byte strBuffer structure and methods. */

//*****************************************************************************

#include "buf_buffer.h"

// global variables

// initialization

void BUF_vidInit(BUF_tstrBuffer* strBuffer, u8 *start, u16 u16Size)
{
	// set start pointer of the strBuffer
	strBuffer->pu8DataPointer = start;
	strBuffer->u16Size = u16Size;
	// initialize index and length
	strBuffer->u16DataIndex = 0;
	strBuffer->u16DataLength = 0;
}

// access routines
u8  BUF_u8GetFromFront(BUF_tstrBuffer* strBuffer)
{
	unsigned char u8data = 0;
	
	// check to see if there's data in the strBuffer
	if(strBuffer->u16DataLength)
	{
		// get the first character from strBuffer
		u8data = strBuffer->pu8DataPointer[strBuffer->u16DataIndex];
		// move index down and decrement length
		strBuffer->u16DataIndex++;
		if(strBuffer->u16DataIndex >= strBuffer->u16Size)
		{
			strBuffer->u16DataIndex %= strBuffer->u16Size;
		}
		strBuffer->u16DataLength--;
	}
	// return
	return u8data;
}

void BUF_vidDumpFromFront(BUF_tstrBuffer* strBuffer, u16 u16Numbytes)
{
	// dump u16Numbytes from the front of the strBuffer
	// are we dumping less than the entire strBuffer?
	if(u16Numbytes < strBuffer->u16DataLength)
	{
		// move index down by u16Numbytes and decrement length by u16Numbytes
		strBuffer->u16DataIndex += u16Numbytes;
		while (strBuffer->u16DataIndex >= strBuffer->u16Size)
		{
			strBuffer->u16DataIndex = strBuffer->u16DataIndex - strBuffer->u16Size;
		}
		strBuffer->u16DataLength -= u16Numbytes;
	}
	else
	{
		// flush the whole strBuffer
		strBuffer->u16DataLength = 0;
	}
}

u8 BUF_u8GetAtIndex(BUF_tstrBuffer* strBuffer, u16 u16Index)
{
	// return character at index in strBuffer
    unsigned char u8Temp;
    u8Temp = strBuffer->u16DataIndex+u16Index;
    while (u8Temp >= strBuffer->u16Size )
    {
    u8Temp = u8Temp - strBuffer->u16Size;
    }
	if (u16Index < strBuffer->u16DataLength)
	{
	return strBuffer->pu8DataPointer[u8Temp];
	}
	else 
	{
	return 0;
	}
}

u8 BUF_u8AddToEnd(BUF_tstrBuffer* strBuffer, u8 u8data)
{

	unsigned char u8BuffIndex;
	// make sure the strBuffer has room
	if(strBuffer->u16DataLength < strBuffer->u16Size)
	{

		u8BuffIndex = (strBuffer->u16DataIndex + strBuffer->u16DataLength);
		while (u8BuffIndex >= strBuffer->u16Size)
		{
			u8BuffIndex = u8BuffIndex - strBuffer->u16Size;
		}
		// save data byte at end of strBuffer
		// [avrlib]strBuffer->pu8DataPointer[(strBuffer->u16DataIndex + strBuffer->datalength) % u08BuffIndex] = u8data;
		strBuffer->pu8DataPointer[u8BuffIndex] = u8data;
		// increment the length
		strBuffer->u16DataLength++;
		// return success
		return 1;
	}
	else return 0;
}

u8 BUF_u8IsNotFull(BUF_tstrBuffer* strBuffer)
{
	// check to see if the strBuffer has room
	// return true if there is room
	return (strBuffer->u16DataLength < strBuffer->u16Size);
}

void BUF_vidFlush(BUF_tstrBuffer* strBuffer)
{
	// flush contents of the strBuffer
	strBuffer->u16DataLength = 0;
}

u8 BUF_u8SearchString(BUF_tstrBuffer* strBuffer,u8 u8StartIndex, const u8 *pu8Str,u8 u8StringLength)
{ 
	u8 u8TextIndexer;
	u8 u8CharCounter = 0;
	u8 u8StringIndexer = 0; 
	
    if (u8StartIndex > strBuffer->u16DataLength )
    {
        return 0xFF;
    }
	u8TextIndexer = strBuffer->u16DataIndex + u8StartIndex;
    if (u8TextIndexer >= strBuffer->u16Size)
	{
        u8TextIndexer = u8TextIndexer - strBuffer->u16Size;
	}
	while (u8CharCounter  < (strBuffer->u16DataLength - u8StartIndex))
		
	{


		if (strBuffer->pu8DataPointer[u8TextIndexer] == pu8Str[u8StringIndexer])
			
        {
			if ((u8StringIndexer + 1) == u8StringLength) 
			{
                return ((u8CharCounter + u8StartIndex) - u8StringIndexer)  ;
			}
			u8CharCounter++;
			u8TextIndexer++;
			if (u8TextIndexer >= strBuffer->u16Size)
			{
				u8TextIndexer = u8TextIndexer - strBuffer->u16Size;
			}
			u8StringIndexer++;     
        }      
        else
        {
			u8StringIndexer= 0;
			u8CharCounter++;
			u8TextIndexer++;
			if (u8TextIndexer >= strBuffer->u16Size)
			{
				u8TextIndexer = u8TextIndexer - strBuffer->u16Size;
			}

        }
	}// while

	return 0xff;
}

u16 BUF_u16GetDataLength(BUF_tstrBuffer* strBuffer)
{
    return strBuffer->u16DataLength;
}
